﻿# Filename:     HostMaintenanceMode.ps1
# Author:	Markus Erlacher
# Description:  Automated Set a Host on Maintenance, support for Single Hosts and Cluster Nodes
# Version: 	1.1  / 06.05.2010 20:30
# Parameters:
#
# -VMMServer		                    System Center Virtual Machine FQDN 		              (Mandatory)
# -VMHostName		                    Host Name for Maintenance 			                  (Mandatory)
# -Maintenance		                    Enable Maintenance if Switch used 		              (DEFAULT: Switch not Set, disable Maintenance)
# -MoveVMs		                        Enable MoveVMs if Switch used inside a Cluster	      (DEFAULT: Switch not Set, Not Move VMs)
# -MoveVMsOnSingleBox	                Enable MoveVMs if Switch used from single Host	      (DEFAULT: Switch not Set, Not Move VMs)
# -OperationManagerServer
#
# Use Custom Field 10 for define Mode of VM for Maintenance:
#
# Maintenance:Saved	- If VM shut be in Saved Mode
# Maintenance:Stop	- If VM shut be Shutdown
#


$VMHostName = "%HOSTNAME%"
$Maintenance = %MAINTENANCE%
$MoveVMs = %MOVEVM%
$MoveVMsOnSingleBox = %MOVEVMSINGLEBOX%




Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager


# Connect to the VMM server.
Get-VMMServer -ComputerName localhost


$VMHost = Get-VMHost -ComputerName $VMHostName
$HostName = $VMHost.Name

$AllVMHostsGroup = Get-VMHostGroup
$ClusterName = $VMHost.HostCluster

$Cluster = Get-VMHostCluster -name $ClusterName


If($Cluster -eq $null)
{
    if($MoveVMsOnSingleBox -eq $true)
    {
        $MoveVMs = $true	
    }
    else
    {
        $MoveVMs = $false	
    }
}
else
{
	$ClusterNodes = Get-VMHost -VMHostCluster $Cluster
}



If($VMHost -ne $null)
{
    if ($Maintenance -eq $true)
    {
        if ($MoveVMs -eq $true)
        {

            Set-VMHost -VMHost $VMHost -AvailableForPlacement $false

            $VMs = Get-VM -VMHost $VMHost
            Foreach ($VM in $VMs)
            {
                $Props = $VM.CustomProperties[9].Split(",")
                $MStatus = $Props[0]
                $AStatus = $VM.Status
                $Text = "$MStatus,VMState:$AStatus,HOST:$HostName"

		        Set-VM -VM $VM -Custom10 $Text -RunAsynchronously 

            }
            
            $VMsforSave = Get-VM -VMHost $VMHost | where { $_.CustomProperties[9] -like "Maintenance:Saved*"}

            if ($VMsforSave.Length -ne 0)
            {
                Foreach ($VM in $VMsforSave)
                {
                    SaveState-VM -VM $VM  
                }
            }

            $VMsforShutdown = Get-VM -VMHost $VMHost | where { $_.CustomProperties[9] -like "Maintenance:Stop*"}
            if ($VMsforShutdown.Length -ne 0)
            {
                Foreach ($VM in $VMsforShutdown)
                {
                    Shutdown-VM -VM $VM  
                }
            }

            $VMsforMove = Get-VM -VMHost $VMHost

            Foreach ($VM in $VMsforMove)
            {
		
                If($Cluster -eq $null)
                {
                    $HostRatings = @(Get-VMHostRating -VM $VM -VMHostGroup $AllVMHostsGroup -PlacementGoal "LoadBalance" -IsMigration | where { $_.Rating -gt 0 } | Sort-Object -property Rating -descending)
                }
                else
                {
                    $HostRatings = @(Get-VMHostRating -VM $VM -VMHost $ClusterNodes -PlacementGoal "LoadBalance" -IsMigration | where { $_.Rating -gt 0 } | Sort-Object -property Rating -descending)
                }

                If($HostRatings.Count -eq "0")
                {

                }
                else
                {
                    If ( $VM.IsHighlyAvailable -eq $true -or $MoveVMsOnSingleBox -eq $true)
                    {
                        $VMTargetHost = $HostRatings[0].VMHost
                        Move-VM -VM $VM -VMHost $VMTargetHost 
                    }
                }
            }

            Disable-VMHost -VMHost $VMHost

        }
        else
        {

            Set-VMHost -VMHost $VMHost -AvailableForPlacement $false

            $VMs = Get-VM -VMHost $VMHost
            Foreach ($VM in $VMs)
            {
                $Props = $VM.CustomProperties[9].Split(",")
                $MStatus = $Props[0]
                $AStatus = $VM.Status
                $Text = "$MStatus,VMState:$AStatus,HOST:$HostName"

                Set-VM -VM $VM -Custom10 $Text
            }

	       Disable-VMHost -VMHost $VMHost

        }

    }
    else
    {

        Enable-VMHost -VMHost $VMHost
        Set-VMHost -VMHost $VMHost -AvailableForPlacement $true


        if ($MoveVMs -eq $true)
        {
            $VMsforThisHost = Get-VM | where { $_.CustomProperties[9] -like "*HOST:$HostName*"}
            Foreach ($VM in $VMsforThisHost)
            {
                if ($VM.HostName -eq $HostName)
                {


                }
                else
                {

                    Move-VM -VM $VM -VMHost $VMHost

                }

                if ($VM.CustomProperties[9] -like "*VMState:Running*")
                {
                    Start-VM -VM $VM -RunAsynchronously 
                }
    		
                $Props = $VM.CustomProperties[9].Split(",")
                $MStatus = $Props[0]

                Set-VM -VM $VM -Custom10 $MStatus -RunAsynchronously 

            }


        }
        else
        {

            $VMsforThisHost = Get-VM | where { $_.CustomProperties[9] -like "*HOST:$HostName*"}
            Foreach ($VM in $VMsforThisHost)
            {
                if ($VM.CustomProperties -eq $null)
                {

                }
                else
                {

                    if ($VM.CustomProperties[9] -like "*VMState:Running*")
                    {
                        Start-VM -VM $VM -RunAsynchronously 
                    }
        		
                    $Props = $VM.CustomProperties[9].Split(",")
                    $MStatus = $Props[0]

                    Set-VM -VM $VM -Custom10 $MStatus -RunAsynchronously 

                }
            }

        }
    }
}